package cn.itcast.nems.studentrecord.service.impl;

import cn.itcast.nems.studentrecord.converter.StudentRecordTransactionConverter;
import cn.itcast.nems.studentrecord.dao.dataobject.StudentRecordStudentDO;
import cn.itcast.nems.studentrecord.dao.entity.StudentRecord;
import cn.itcast.nems.studentrecord.dao.mapper.StudentRecordStudentRelationshipMapper;
import cn.itcast.nems.studentrecord.dto.ClazzStudentResultDTO;
import cn.itcast.nems.studentrecord.dto.StudentRecordStudentDTO;
import cn.itcast.nems.studentrecord.dto.change.StudentRecordJournalInDateChangeDTO;
import cn.itcast.nems.studentrecord.service.StudentRecordClazzStartDateChangedService;
import cn.itcast.nems.studentrecord.service.studentrecord.StudentRecordService;
import cn.itcast.nems.studentrecord.service.studentrecord.StudentRecordTransactionService;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Collections;
import java.util.List;

/**
 * author liyong
 * create: 2024-01-11 20:18:15
 **/
@Service
@AllArgsConstructor
public class StudentRecordClazzStartDateChangedServiceImple implements StudentRecordClazzStartDateChangedService {
    private final StudentRecordStudentRelationshipMapper studentRecordStudentRelationshipMapper;
    private final StudentRecordService studentRecordService;
    private final StudentRecordTransactionService studentRecordTransactionService;

    @Override
    public ClazzStudentResultDTO findStudents(int clazzId, LocalDate oldStartDate, LocalDate newStartDate) {
        final int totalCount = this.studentRecordService.findValidStudentRecordCount(clazzId);
        if (oldStartDate.isEqual(newStartDate)) {
            return new ClazzStudentResultDTO(totalCount, Collections.emptyList());
        }
        List<StudentRecordStudentDO> studentDOS;
        if (newStartDate.isAfter(oldStartDate)) {
            studentDOS = this.studentRecordStudentRelationshipMapper.selectChangeDateAfterInvolveStudents(clazzId, newStartDate.atStartOfDay());
        } else {
            studentDOS = this.studentRecordStudentRelationshipMapper.selectChangeDateBeforeInvolveStudents(clazzId, oldStartDate.atTime(LocalTime.MAX));
        }
        final List<StudentRecordStudentDTO> dtos = studentDOS
                .stream()
                .map(s -> {
                    StudentRecordStudentDTO dto = new StudentRecordStudentDTO();
                    BeanUtils.copyProperties(s, dto);
                    return dto;
                })
                .toList();
        return new ClazzStudentResultDTO(totalCount, dtos);
    }

    @Override
    @Transactional
    public void updateStudentRecordInDates(List<StudentRecordJournalInDateChangeDTO> studentRecords) {
        final List<StudentRecord> updateCmds = studentRecords.stream().map(s -> {
            StudentRecord update = new StudentRecord();
            update.setId(s.getStudentRecordId());
            update.setInDate(s.getAfterInDate().atStartOfDay());
            return update;
        }).toList();
        this.studentRecordService.batchUpdateById(updateCmds);

        studentRecords
                .stream()
                .map(StudentRecordTransactionConverter::convertIn)
                .forEach(t -> this.studentRecordTransactionService.chargeAgainstInClazz(t));
    }

}
